package me.luger.core.commom.util;

import java.io.File;
import java.io.FileFilter;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLDecoder;
import java.util.*;

/**
 * ClazzUtil
 *
 * @author luger
 * @date 2016/11/18 0018
 */
public class ClazzUtil {
    /**
     * 获得包下面的所有的class
     *
     * @param pack package完整名称
     * @return List包含所有class的实例
     */
    public static List<Class> getClasssFromPackage(String pack) {
        List<Class> clazzs = new ArrayList<Class>();

        // 是否循环搜索子包
        boolean recursive = true;

        // 包名字
        String packageName = pack;
        // 包名对应的路径名称
        String packageDirName = packageName.replace('.', '/');

        Enumeration<URL> dirs;

        try {
            dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
            while (dirs.hasMoreElements()) {
                URL url = dirs.nextElement();

                String protocol = url.getProtocol();

                if ("file".equals(protocol)) {
                    String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                    findClassInPackageByFile(packageName, filePath, recursive, clazzs);
                } else if ("jar".equals(protocol)) {

                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return clazzs;
    }

    /**
     * 在package对应的路径下找到所有的class
     *
     * @param packageName package名称
     * @param filePath    package对应的路径
     * @param recursive   是否查找子package
     * @param clazzs      找到class以后存放的集合
     */
    public static void findClassInPackageByFile(String packageName, String filePath, final boolean recursive, List<Class> clazzs) {
        File dir = new File(filePath);
        if (!dir.exists() || !dir.isDirectory()) {
            return;
        }
        // 在给定的目录下找到所有的文件，并且进行条件过滤
        File[] dirFiles = dir.listFiles(new FileFilter() {

            @Override
            public boolean accept(File file) {
                boolean acceptDir = recursive && file.isDirectory();// 接受dir目录
                boolean acceptClass = file.getName().endsWith("class");// 接受class文件
                return acceptDir || acceptClass;
            }
        });

        for (File file : dirFiles) {
            if (file.isDirectory()) {
                findClassInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, clazzs);
            } else {
                String className = file.getName().substring(0, file.getName().length() - 6);
                try {
                    clazzs.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + "." + className));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static Class filterGgilibClazz(Class clazz) throws ClassNotFoundException {
        String clazzStr = clazz.toString();
        if (clazzStr.contains("$$")) {
            clazzStr = clazzStr.substring(0, clazzStr.indexOf("$$"));
        }
        if (clazzStr.contains("class ")) {
            clazzStr = clazzStr.replace("class ", "");
        }
        clazz = Class.forName(clazzStr);
        return Class.forName(clazzStr);
    }

    public static String getBeanName(Class clazz) {
        String clazzStr = clazz.toString();
        if (clazzStr.contains("$$")) {
            clazzStr = clazzStr.substring(0, clazzStr.indexOf("$$"));
        }
        if (clazzStr.contains("class ")) {
            clazzStr = clazzStr.replace("class ", "");
        }
        return clazzStr.substring(clazzStr.lastIndexOf(".") + 1);
    }

    /**
     * java bean 转 map
     * @param javaBean
     * @param ignoreNull
     * @return
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> bean2Map(Object javaBean, boolean ignoreNull) {
        Map<String, Object> ret = new HashMap<String, Object>();
        try {
            Method[] methods = javaBean.getClass().getDeclaredMethods();
            for (Method method : methods) {
                if (method.getName().startsWith("get")) {
                    String field = method.getName();
                    field = field.substring(field.indexOf("get") + 3);
                    field = field.toLowerCase().charAt(0) + field.substring(1);
                    Object value = method.invoke(javaBean, (java.lang.Object[]) null);
                    if(!ignoreNull || null != value){
                        ret.put(field, value);
                    }
                }
            }
        } catch (Exception e) {
        }
        return ret;
    }

    public static List<Map<String,Object>> BeanList2Map(List objList,boolean ignoreNull){
        List<Map<String,Object>> retList = new ArrayList<Map<String, Object>>();
        for(Object obj : objList){
            retList.add(bean2Map(obj,ignoreNull));
        }
        return retList;
    }
}
